package zap

import (
	"errors"
	"fmt"
	"os"
	"time"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

type ZapLogger struct {
	*zap.Logger
	cfg *Config
}

type Config struct {
	Level         string
	Format        string
	Director      string
	EncodeLevel   string
	StacktraceKey string
	MaxAge        int32
	LogInConsole  bool
	LogInFile     bool
	ShowLine      bool
}

func CustomTimeEncoder(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {
	encoder.AppendString(t.Local().Format("2006/01/02 - 15:04:05.000"))
}

func pathExists(path string) (bool, error) {
	fi, err := os.Stat(path)
	if err == nil {
		if fi.IsDir() {
			return true, nil
		}
		return false, errors.New("file with the same name exists")
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// NewZapLogger return a zap logger.
func NewZapLogger(config *Config, opts ...zap.Option) *zap.Logger {
	if config.LogInFile {
		if config.Director == "" {
			config.Director = "logs"
		}
		if ok, _ := pathExists(config.Director); !ok {
			fmt.Printf("create %v directory\n", config.Director)
			_ = os.Mkdir(config.Director, os.ModePerm)
		}
	}

	zlog := &ZapLogger{cfg: config}
	cores := zlog.GetZapCores()

	logger := zap.New(zapcore.NewTee(cores...), opts...)

	if config.ShowLine {
		logger = logger.WithOptions(zap.AddCaller())
	}
	return logger
}
